package com.tian.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tian.config.RedisCacheUtil;
import com.tian.dao.entity.UserInfo;
import com.tian.dao.entity.UserRole;
import com.tian.dao.mapper.UserInfoMapper;
import com.tian.dto.req.UserInfoAddReqDto;
import com.tian.dto.req.UserInfoReqDto;
import com.tian.dto.resp.PageDto;
import com.tian.dto.resp.UserInfoRespDto;
import com.tian.enums.ResultCode;
import com.tian.exception.BusinessException;
import com.tian.service.UserInfoService;
import com.tian.service.UserRoleService;
import com.tian.utils.Result;
import com.tian.utils.TokenUtil;
import com.tian.utils.UserCacheUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * {@code @description:} 用户信息具体实现类
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-07-28 12:03
 * {@code @version:} 1.0
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserRoleService userRoleService;

    @Resource
    private RedisCacheUtil redisCacheUtil;
    @Override
    public Result findByCondition(UserInfoReqDto userInfoReqDto) {
        if ("admin".equals(userInfoReqDto.getUserName())) {
            throw new BusinessException(ResultCode.USER_ROLE_ERROR);
        }
        if ("111111".equals(userInfoReqDto.getPassword())) {
            throw new RuntimeException("你的系统异常了");
        }
        Wrapper<UserInfo> wrapper = Wrappers.<UserInfo>lambdaQuery()
                .eq(UserInfo::getUserName, userInfoReqDto.getUserName())
                .eq(UserInfo::getPassword, userInfoReqDto.getPassword());
        return Result.success(this.baseMapper.selectList(wrapper));
    }

    @Override
    public Result<UserInfoRespDto> login(UserInfoReqDto userInfoReqDto) {


        Wrapper<UserInfo> wrapper = Wrappers.<UserInfo>lambdaQuery()
                .eq(UserInfo::getUserName, userInfoReqDto.getUserName())
                .eq(UserInfo::getPassword, userInfoReqDto.getPassword());
        UserInfo userInfo = this.baseMapper.selectOne(wrapper);
        if (userInfo == null) {
            return Result.fail(ResultCode.USER_NAME_OR_PASSWORD_ERROR);
        }

        UserInfoRespDto userInfoRespDto = new UserInfoRespDto();
        BeanUtils.copyProperties(userInfo, userInfoRespDto);
        String token = TokenUtil.getToken(userInfo.getId() + "-" + userInfo.getUserName());
        userInfoRespDto.setToken(token);
        userInfoRespDto.setAvatar("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");

        List<UserRole> list = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userInfo.getId()));
        if(!CollectionUtils.isEmpty(list)) {
            userInfoRespDto.setRoleId(list.get(0).getRoleId());
            UserCacheUtil.setUser(userInfoRespDto);
            redisCacheUtil.setCacheObject(token, userInfoRespDto);
        }
        return Result.success(userInfoRespDto);
    }

    @Override
    public Result<PageDto<List<UserInfoRespDto>>> list(UserInfoReqDto userInfoReqDto) {
        Wrapper<UserInfo> wrapper = Wrappers.<UserInfo>lambdaQuery().eq(UserInfo::getStatus, 0);
        List<UserInfoRespDto> userInfoRespDtoList = new ArrayList<>();
        Page<UserInfo> mapPage = this.baseMapper.selectPage(new Page<>(1, 10), wrapper);
        mapPage.getRecords().forEach(userInfo -> {
            UserInfoRespDto userInfoRespDto = new UserInfoRespDto();
            BeanUtils.copyProperties(userInfo, userInfoRespDto);
            userInfoRespDto.setGenderStr(1==userInfo.getGender() ? "男" : "女");
            Wrapper<UserRole> userRoleWrapper = Wrappers.<UserRole>lambdaQuery()
                            .eq(UserRole::getUserId, userInfo.getId());
            List<UserRole> list = userRoleService.list(userRoleWrapper);
            if(!CollectionUtils.isEmpty(list)) {
                userInfoRespDto.setRoleId(list.get(0).getRoleId());
            }else {
                userInfoRespDto.setRoleId(1);
            }
            userInfoRespDtoList.add(userInfoRespDto);
        });
        int totalCount = (int) mapPage.getTotal();
        PageDto<List<UserInfoRespDto>> pageDto = new PageDto<>();
        pageDto.setData(userInfoRespDtoList);
        pageDto.setTotalPage(totalCount/10+(totalCount%10>0?1:0) );
        pageDto.setTotalCount(totalCount);
        return Result.success(pageDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> registry(UserInfoAddReqDto userInfoAddReqDto) {
        Wrapper<UserInfo> wrapper = Wrappers.<UserInfo>lambdaQuery()
                .eq(UserInfo::getUserName,userInfoAddReqDto.getUserName());
        Integer count = this.baseMapper.selectCount(wrapper);
        if(count>0) {
            return Result.fail(ResultCode.USER_NAME_EXIST);
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName(userInfoAddReqDto.getUserName());
        userInfo.setPassword(userInfoAddReqDto.getPassword());
        userInfo.setGender("男".equals(userInfoAddReqDto.getGender()) ? 1 : 0);
        userInfo.setStatus(0);
        userInfo.setCreateTime(new Date());
        userInfo.setPhone(userInfoAddReqDto.getPhone());
        this.baseMapper.insert(userInfo);
        UserRole userRole = new UserRole();
        userRole.setUserId(userInfo.getId());
        userRole.setRoleId(userInfoAddReqDto.getRoleId());
        userRoleService.save(userRole);

        return Result.success(Boolean.TRUE);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> update(UserInfoAddReqDto userInfoAddReqDto) {
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userInfoAddReqDto, userInfo);
        userInfo.setGender("1".equals(userInfoAddReqDto.getGender()) ? 1 : 0);
        this.baseMapper.updateById(userInfo);
        List<UserRole> list = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userInfo.getId()));
        if(list.size() == 0) {
            UserRole userRole = new UserRole();
            userRole.setUserId(userInfoAddReqDto.getId());
            userRole.setRoleId(userInfoAddReqDto.getRoleId());
            userRoleService.save(userRole);
            return Result.success(Boolean.TRUE);
        }
        UserRole userRole = list.get(0);
        //一个用户只有一个角色，所以直接更新即可
        userRole.setUserId(userInfo.getId());
        userRole.setRoleId(userInfoAddReqDto.getRoleId());
        userRoleService.saveOrUpdate(userRole);
        return Result.success(Boolean.TRUE);
    }

    @Override
    public Result<Boolean> delete(Integer id) {
        UserInfo userInfo = this.baseMapper.selectById(id);
        userInfo.setStatus(1);
        this.baseMapper.updateById(userInfo);
        return Result.success(Boolean.TRUE);
    }
}
